﻿using System;
using System.Windows;
using System.Windows.Media;

namespace Bookvar.UI
{
    public class BezierTopicConnector : ConnectingShapeTopicConnector
    {
        protected override ConnectingShape ConstructConnectingShape()
        {
            return new BezierConnectingShape();
        }

        private class BezierConnectingShape : ConnectingShape
        {
            private PathGeometry geometry;

            static BezierConnectingShape()
            {
                StartPointProperty.OverrideMetadata( typeof ( BezierConnectingShape ),
                                                     new FrameworkPropertyMetadata( OnPointChanged ) );
                EndPointProperty.OverrideMetadata( typeof ( BezierConnectingShape ),
                                                   new FrameworkPropertyMetadata( OnPointChanged ) );
            }

            private static void OnPointChanged( DependencyObject d, DependencyPropertyChangedEventArgs e )
            {
                BezierConnectingShape shape = (BezierConnectingShape)d;
                shape.geometry = null;
            }

            protected override Geometry DefiningGeometry
            {
                get
                {
                    if ( geometry == null )
                    {
                        CalculateGeometry();
                    }
                    return geometry;
                }
            }

            private void CalculateGeometry()
            {
                Point startPoint, endPoint;
                if ( StartPoint.X < EndPoint.X )
                {
                    startPoint = StartPoint;
                    endPoint = EndPoint;
                }
                else
                {
                    startPoint = EndPoint;
                    endPoint = StartPoint;
                }

                geometry = new PathGeometry();
                PathFigure figure = new PathFigure();

                figure.StartPoint = startPoint;

                double num = Math.Max( Math.Abs( endPoint.X - startPoint.X ) / 2.0, 20.0 );

                BezierSegment segment = new BezierSegment();
                segment.Point1 = new Point( startPoint.X + num, startPoint.Y );
                segment.Point2 = new Point( endPoint.X - num, endPoint.Y );
                segment.Point3 = endPoint;

                figure.Segments.Add( segment );
                geometry.Figures.Add( figure );
            }
        }
    }
}